package com.david.controller;

import com.david.model.Person;
import com.david.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.WebSession;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.awt.*;
import java.util.Random;
import java.util.stream.IntStream;

// 注解式
// 函数式
@RestController
@RequestMapping("/person")
public class PersonController {


    @Autowired
    PersonService personService;

    /**
     * 执行的顺序：
     *
     * 1.----1
     * 2.----2
     * 3.异步方法getPerson
     *
     * main方法中的线程和容器调用mono方法中的线程是同一个线程（参考在单一线程中实现观察者模式）
     *
     * @return
     */
    @GetMapping("")
    Mono<Object> get(){
        System.out.println("线程get"+Thread.currentThread().getName());
        System.out.println("---1");
        //异步
        Mono<Object> mono = Mono.create(sink -> {
            sink.success(personService.getPerson());//组装数据序列  当数据准备好后装入sink中，方法再被调起
        }).doOnSubscribe(sub->{
            System.out.println("subscribe"+Thread.currentThread().getName());
            System.out.println("subscribe");//步骤1：订阅数据
        }).doOnNext(data->{
            System.out.println("data"+data);//步骤2：得到数据
        }).doOnSuccess(onSuccess->{
            System.out.println("success");//步骤3：整体完成
        });
        System.out.println("---2");
        //SpringMVC 需要return的值需要在此处准备好再return，要不然直接抛异常
        return mono;
    }

    /**
     *
     * @param request netty中的request和response，相当于servlet中的request和response
     * @param name
     * @param session netty中的Session
     * @return
     */
    @GetMapping("/xxoo")
    Mono<Object> get2(ServerHttpRequest request, String name, WebSession session){
        System.out.println("name"+name);
        System.out.println("request"+request);
        System.out.println("我要对session进行set了~");
        if (StringUtils.isEmpty(session.getAttribute("code"))){
            session.getAttributes().put("code",250);
        }
        System.out.println("code="+session.getAttribute("code"));
        return Mono.just("么么哒");
    }



    @GetMapping(value = "/sse",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> sse(){
        //1.封装对象
        Flux<String> flux = Flux.fromStream(IntStream.range(1, 1000).mapToObj(i -> {//Java8及以上的Stream
            try {
                Thread.sleep(new Random().nextInt(3000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "xxoo"+i;
        })).doOnSubscribe(sub->{
            System.out.println("sub");
        }).doOnComplete(()->{
            System.out.println("complete");
        }).doOnNext(data->{
            System.out.println("有data了"+data);
        });
        //2.将对象和对象的方法return给netty容器
        return flux;
    }

}
